// ## 2023/12/01 # 铃 # 增加快速征召功能,目的是把预备兵转化为士兵. ##

namespace 快速征召
{

	// ================ CUSTOMIZE ================

	const int TP_COST = 200;
	const int ACTION_COST = 50;
	const int GOLD_COST = 2000;
	const int ENERGY_GAIN = 10;

	// ===========================================

	const int KEY = pk::hash("快速征召");

	class Main
	{
		bool 调试模式 = false;
		pk::building @building_;
		pk::force @force_;
		pk::person @taishu_;
		pk::city @city_;

		Main()
		{
			pk::bind(202, pk::trigger202_t(onAIRunningOrder));
			add_menu();
		}

		void add_menu()
		{
			pk::menu_item item;
			item.menu = 101;
			 item.pos = 9;
			item.shortcut = "X";
			item.init = pk::building_menu_item_init_t(init);
			item.is_enabled = pk::menu_item_is_enabled_t(isEnabled);
			item.get_text = pk::menu_item_get_text_t(getText);
			item.get_desc = pk::menu_item_get_desc_t(getDesc);
			item.handler = pk::menu_item_handler_t(handler);
			pk::add_menu_item(item);
		}

		void init(pk::building @building)
		{
			@building_ = @building;
			@force_ = pk::get_force(building.get_force_id());
			@taishu_ = pk::get_taishu_id(building) == -1 ? null : pk::get_person(pk::get_taishu_id(building));
			@city_ = pk::building_to_city(building);
		}

		string getText()
		{
			return pk::encode("快速征召");
		}

		bool isEnabled()
		{
			auto person_list = pk::get_idle_person_list(building_);
			int result = check_avaliable(building_, person_list);
			if (result != 0)
				return false;
			else
				return true;
		}

		int check_avaliable(pk::building @building, pk::list<pk::person @> list)
		{
			if (ch::get_base_p(building.get_id()).enlist_done)
				return 1;
			else if (list.count == 0)
				return 2;
			else if (pk::get_district(building.get_district_id()).ap < ACTION_COST)
				return 3;
			else if (pk::get_troops(building) >= pk::get_max_troops(building))
				return 4;
			else if (pk::get_force(building.get_force_id()).tp < TP_COST)
				return 5;
			else if (pk::get_gold(building) < GOLD_COST)
				return 6;
			else if (ch::get_base_p(building.get_id()).mil_pop_av <= 2000)
				return 7;
			else
				return 0;
		}

		string getDesc()
		{
			auto person_list = pk::get_idle_person_list(building_);
			int result = check_avaliable(building_, person_list);
			switch (result)
			{
			case 1:
				return pk::encode("已执行过募兵或快速征召");
			case 2:
				return pk::encode("没有可执行的武将. ");
			case 3:
				return pk::encode(pk::format("行动力不足 (必须 {} 行动力)", ACTION_COST));
			case 4:
				return pk::encode("兵力已达最大值.");
			case 5:
				return pk::encode(pk::format("技巧不足.(必须{} 技巧)", TP_COST));
			case 6:
				return pk::encode(pk::format("资金不足 (必须 {} 资金)", GOLD_COST));
			case 7:
				return pk::encode("预备兵不足");
			case 0:
				return pk::encode(pk::format("从预备役中征召士兵.(消耗：金{} 技巧点{}, 行动力{})", GOLD_COST, TP_COST, ACTION_COST));
			default:
				return pk::encode("");
			}
			return pk::encode("");
		}

		bool handler()
		{

			int choise = pk::choose(pk::encode("是否开始募集士兵?\n(兵源来自\x1b[1x预备兵,\x1b[0x需要消耗\x1b[1x2000\x1b[0x金)"), {pk::encode(" 是 "), pk::encode(" 否 ")});
			if (choise == 1)
				return false;
			else
			{
				if (ch::get_base_p(building_.get_id()).mil_pop_av < 2000)
					if (pk::choose(pk::encode(pk::format("目前预备兵不足({})，募集效率较低，是否继续?", ch::get_base_p(building_.get_id()).mil_pop_av)), {pk::encode(" 是 "), pk::encode(" 否 ")}) == 1)
						return false;
			}

			pk::list<pk::person @> person_list = pk::get_idle_person_list(building_);
			if (person_list.count == 0)
				return false;

			pk::list<pk::person @> person_sel;
			person_list.sort(function(a, b) {
				return (a.stat[武将能力_魅力] > b.stat[武将能力_魅力]);
			});

			person_sel = pk::person_selector(pk::encode("武将选择"), pk::encode("选择可执行的武将."), person_list, 1, 1);
			if (person_sel.count == 0)
				return false;

			return run_order(person_sel, building_);
		}

		//======================================================AI快速征召==============================================//

		void onAIRunningOrder(pk::ai_context @context, pk::building @building, int cmd)
		{
			if (cmd == 据点AI_快速征召)
			{
				pk::list<pk::person @> person_sel;
				if (run_order_before(context, person_sel, building))
				{
					run_order(person_sel, building);
					ch::remove_idle_person(context, person_sel);
				}
				else if (调试模式)
					pk::trace(pk::decode(pk::get_name(building)) + "据点AI_快速征召 不满足");
			}
		}

		bool run_order_before(pk::ai_context @context, pk::list<pk::person @> &out person_sel, pk::building @building0)
		{
			pk::list<pk::person @> person_list = pk::get_idle_person_list(building0);

			if ((building0.get_id() < 0 or building0.get_id() >= 据点_末))
				return false;

			if (!context.base[building0.get_id()].enemies_around5)
				return false; // 无敌人威胁时，少粮不快速征召

			pk::int_int 据点周边兵力 = ch::base_range_self_and_enemy_troops(building0, 5);
			int 周围敌方兵力 = 据点周边兵力.second; // ch::enemy_troop_base_range(building);
			int 周围己方兵力 = 据点周边兵力.first;	// ch::self_troop_base_near_distance(building, 5);
			int 据点内可用战斗兵力 = ch::get_max_effective_troops(building0);

			if (周围敌方兵力 < 10000) // 威胁不大就不快速征召
				return false;

			if (据点内可用战斗兵力 + 周围己方兵力 > 周围敌方兵力) // 能打的过就不快速征召
				return false;

			if (pk::get_gold(building0) < 2 * GOLD_COST) // 钱不多就不快速征召
				return false;

			if (building0.hp < 3000) // 城快破了就不快速征召
				return false;

			if (ch::get_base_p(building0.get_id()).mil_pop_av < 2000)
				return false;

			if (check_avaliable(building0, person_list) != 0)
			{
				return false;
			}
			person_list.sort(function(a, b) {
				return (a.stat[武将能力_魅力] > b.stat[武将能力_魅力]);
			});
			person_sel.add(person_list[0]);
			return true;
		}

		bool run_order(pk::list<pk::person @> person_sel, pk::building @building0)
		{
			if (building0 is null)
				return false;
			if (person_sel[0] is null)
				return false;

			string actor_name = pk::decode(pk::get_name(person_sel[0]));
			pk::person @young_man = pk::get_person(武将_士兵);

			if (pk::is_player_controlled(building0))
			{
				pk::message_box(pk::encode(pk::format("\x1b[1x{}\x1b[0x大人, 我们已经整装待发!", actor_name)), young_man);
				pk::message_box(pk::encode("从今天起你们就是勇往无前的士兵!"), person_sel[0]);
			}
			else
			{
				if (pk::is_in_screen(building0.pos))
				{
					pk::say(pk::encode("!敌军已兵临城下!快征召预备兵入伍!"), person_sel[0], building0);
					pk::say(pk::encode(pk::format("\x1b[1x{}\x1b[0x我们已经整装待发!", actor_name)), young_man, building0);
				}

				pk::history_log(building0.pos, (pk::get_force(building0.get_force_id())).color, pk::encode(pk::format("\x1b[1x{}\x1b[0x在{}紧急征召部分预备役入伍.", actor_name, pk::decode(pk::get_name(building0)))));
				if (调试模式) pk::trace(pk::decode(pk::get_name(building0)) + "进行快速征召");
			}

			auto base_t = ch::get_base_p(building0.get_id());
			int troops_ = int(2000 + pk::rand(100) + person_sel[0].stat[武将能力_魅力] * 10 * (building0.is_player() ? 1.0 : 1.2));
			troops_ = int(troops_ * (building0.is_player() ? 玩家征兵倍率 : 电脑征兵倍率) / 100.f);
			troops_ = pk::min(troops_, int(base_t.mil_pop_av));
			base_t.mil_pop_av = pk::max(0, base_t.mil_pop_av - troops_);

			if (pk::is_player_controlled(building0))
			{
				string t = "\x1b[1x" + troops_ + "\x1b[0x名预备兵加入部队, 士气增加\x1b[1x" + ENERGY_GAIN + "\n\x1b[0x消耗\x1b[1x" + GOLD_COST + "\x1b[0x金,\x1b[1x" + TP_COST + "\x1b[0x技巧.";
				pk::message_box(pk::encode(t));
			}

			auto district = pk::get_district(building0.get_district_id());
			ch::add_tp(pk::get_force(building0.get_force_id()), -TP_COST, building0.get_pos());
			pk::add_ap(district, -ACTION_COST);
			pk::add_gold(building0, -GOLD_COST, true);
			pk::add_troops(building0, int(troops_ * 1.0f), true); 
			pk::add_energy(building0, 10, true);
			ch::get_base_p(building0.get_id()).enlist_done = true;
			person_sel[0].action_done = true;

			return true;
		}

	} Main main;
}